﻿﻿using DeviceCommons.DataHandling;
using DeviceCommons.DeviceMessages.Abstractions;
using DeviceCommons.DeviceMessages.Enums;
using DeviceCommons.DeviceMessages.Models.V1;
using DeviceCommons.Validation;
using System.Buffers;

namespace DeviceCommons.DeviceMessages.Serialization.V1.Serializers
{
    public class DeviceMessageInfoReadingStateSerializer : AbstractMessageSerializer<IDeviceMessageInfoReadingState>, IDeviceMessageInfoReadingStateSerializer
    {
        public DeviceMessageInfoReadingStateSerializer() : base(new DeviceMessageInfoReadingState())
        {
        }
        public override void Serializer(ArrayBufferWriter<byte> writer, IDeviceMessageInfoReadingState model)
        {
            if (model == null) throw new ArgumentNullException(nameof(model));
            if (model.Value == null) 
                throw new DeviceMessageValidationException(
                    ValidationErrorType.InvalidStateValue,
                    "状态值不能为null",
                    nameof(model.Value),
                    "非空字节数组",
                    null);

            StateValueTypeEnum valueType = (StateValueTypeEnum)model.Type;
            int valueLength = model.Value?.Length ?? 0;

            if (valueType != StateValueTypeEnum.String && valueType != StateValueTypeEnum.Binary)
            {
                int expectedLength = DeviceMessageUtilities.GetValueLength(valueType, null);
                if (valueLength != expectedLength)
                    throw new DeviceMessageValidationException(
                        ValidationErrorType.StateValueTypeMismatch,
                        $"状态值长度与类型不匹配。期望长度: {expectedLength}, 实际长度: {valueLength}",
                        nameof(model.Value),
                        $"{expectedLength} 字节",
                        $"{valueLength} 字节");
            }

            int totalLength = 2;
            if (valueType == StateValueTypeEnum.String) totalLength += 1;
            else if (valueType == StateValueTypeEnum.Binary) totalLength += 2;
            totalLength += valueLength;

            int existingLength = writer.WrittenCount;

            using var pool = DeviceMessageArrayPool.MemoryPool.Rent(existingLength + 1);

            writer.WrittenMemory.ToArray().CopyTo(pool.Memory);
            ReadOnlySpan<byte> existingData = pool.Memory.Span[..existingLength];


            writer.Clear();

            writer.Write([model.SID]);
            writer.Write([model.Type]);

            switch (valueType)
            {
                case StateValueTypeEnum.String:
                    if (valueLength > byte.MaxValue) 
                        throw new DeviceMessageValidationException(
                            ValidationErrorType.StringLengthExceeded,
                            $"字符串类型状态值长度超出1字节表示范围",
                            nameof(model.Value),
                            $"<= {byte.MaxValue} 字节",
                            $"{valueLength} 字节");
                    writer.Write([(byte)valueLength]);
                    break;

                case StateValueTypeEnum.Binary:
                    writer.Write(BitConverter.GetBytes((ushort)valueLength));
                    break;
            }
            writer.Write(model.Value);

            if (existingLength > 0) writer.Write(existingData);
        }
    }
}
